package com.itheima.health.service.advice;

import com.alibaba.fastjson.JSON;
import com.itheima.health.constant.RedisConstant;
import com.itheima.health.dao.AdviceDao;
import com.itheima.health.pojo.CheckGroup;
import com.itheima.health.pojo.CheckItem;
import com.itheima.health.pojo.Setmeal;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import redis.clients.jedis.JedisPool;

import java.util.List;

@Component
@Aspect
public class RedisAdvice {
    @Autowired
    AdviceDao adviceDao;
    @Autowired
    JedisPool jedisPool;

    //修改检查项时删除redis中对应id的套餐
    @AfterReturning(value = "execution(public void com.itheima.health.service.impl.CheckItemServiceImpl.edit(..))&&args(checkItem)", argNames = "checkItem")
    public void checkItemDML(CheckItem checkItem) {
        List<Integer> setmealIds = adviceDao.findSetmealIdsByCheckItemId(checkItem.getId());
        if (setmealIds != null && setmealIds.size() > 0) {
            for (Integer setmealId : setmealIds) {
                jedisPool.getResource().del(Integer.toString(setmealId));
            }
        }
    }

    //修改检查组时删除redis中对应id的套餐
    @AfterReturning(value = "execution(public void com.itheima.health.service.impl.CheckGroupServiceImpl.edit(..))&&args(checkGroup,..)", argNames = "checkGroup")
    public void checkGroupDML(CheckGroup checkGroup) {
        List<Integer> setmealIds = adviceDao.findSetmealIdsByCheckGroupId(checkGroup.getId());
        if (setmealIds != null && setmealIds.size() > 0) {
            for (Integer setmealId : setmealIds) {
                jedisPool.getResource().del(Integer.toString(setmealId));
            }
        }
    }

    //修改套餐时删除redis中对应id套餐，及所有的套餐缓存
    @AfterReturning(value = "execution(public void com.itheima.health.service.impl.SetmealServiceImpl.editSetmeal(..))&&args(setmeal,..)", argNames = "setmeal")
    public void editSetmealAfter(Setmeal setmeal) {
        jedisPool.getResource().del(Integer.toString(setmeal.getId()));
        jedisPool.getResource().del(RedisConstant.SETMEAL_ALL);
    }

    //删除了套餐时同时删除redis中对应的id套餐信息，以及所有的套餐缓存
    @AfterReturning(value = "execution(public void com.itheima.health.service.impl.SetmealServiceImpl.deleteSetmealById(..))&&args(id)", argNames = "id")
    public void deleteSeteamlByIdAfter(Integer id) {
        jedisPool.getResource().del(Integer.toString(id));
        jedisPool.getResource().del(RedisConstant.SETMEAL_ALL);
    }

    //添加套餐时删除redis中所有套餐列表
    @AfterReturning(value = "execution(public void com.itheima.health.service.impl.SetmealServiceImpl.add(..))")
    public void addSeteamlAfter() {
        jedisPool.getResource().del(RedisConstant.SETMEAL_ALL);
    }

    //查询所有套餐时，将查到的套餐信息存入redis中，环绕通知
    @Around(value = "execution(* com.itheima.health.service.impl.SetmealServiceImpl.findAll(..))")
    public List<Setmeal> findAllSetmeal(ProceedingJoinPoint pjp) throws Throwable {
        String setmealListStr = jedisPool.getResource().get(RedisConstant.SETMEAL_ALL);
        if (setmealListStr == null) {
            List<Setmeal> setmeals = (List<Setmeal>) pjp.proceed();
            setmealListStr = JSON.toJSONString(setmeals);
            jedisPool.getResource().set(RedisConstant.SETMEAL_ALL, setmealListStr);
        }
        return JSON.parseArray(setmealListStr, Setmeal.class);
    }

    //点击某一项套餐时，查询到对应id的套餐并将其以id为键存入redis中
    @Around(value = "execution(* com.itheima.health.service.impl.SetmealServiceImpl.findById(..))")
    public Setmeal findByIdSetmeal(ProceedingJoinPoint pjp) throws Throwable {
        Object[] args = pjp.getArgs();
        Integer id = (Integer) args[0];
        String setmealStr = jedisPool.getResource().get(Integer.toString(id));
        if (setmealStr == null) {
            Setmeal setmeal = (Setmeal) pjp.proceed();
            setmealStr = JSON.toJSONString(setmeal);
            jedisPool.getResource().set(Integer.toString(id), setmealStr);
        }
        return JSON.parseObject(setmealStr, Setmeal.class);
    }
}